#pragma once

#include <stdio.h>
#include <stdlib.h>

#include <string>
#include <vector>

#include "exceptions.h"

namespace ParserCombinators
{

using std::string;
using std::vector;

void consume(string &in, const string &token);
bool optionalConsume(string &in, const string &token);
int parseInt(string &in);
void ignoreWhitespace(string &in);

template<class T> vector<T> parseList(string &in, T (*parser)(string&))
{
    ignoreWhitespace(in);
    vector<T> ret;
    consume(in, "[");
    if (optionalConsume(in, "]")) 
        return ret;
    try 
    {
        ret.push_back(parser(in));
        while (true)
        {
            consume(in, ",");
            ret.push_back(parser(in));
        }
    } 
    catch (TException &e)
    {
        if (e.number == 0)
        {
            // end of list!
            consume(in, "]");
            return ret;
        } 
        else
        {
            // unknown error
            throw e;
        }
    }
}

} // namespace ParserCombinators
